import React, { Component } from 'react';
import { graphql, compose } from 'react-apollo';
import gql from 'graphql-tag';
import { propType, filter } from 'graphql-anywhere';
import {
  View, ActivityIndicator, Alert, TouchableOpacity,
  StyleSheet, ScrollView, Linking
} from 'react-native';
import { Icon, Button, List, ListItem } from 'react-native-elements';
import update from 'immutability-helper';
import Loader from './widgets/Loader';
import OrderPricingTable from './components/OrderPricingTable';
import OrderShipping from './components/OrderShipping';
import RefreshScrollView from './widgets/RefreshScrollView';
import { toast, primaryColor, executor, checkoutNextPage, deleteOrderEvents, isPickupOrder, getDirection } from './utils';
import { setNewOrderItems } from './clientStorage';
import { printOrder } from './printerUtils';
import Communications from 'react-native-communications';

const styles = StyleSheet.create({
  paddingTop: {
    paddingTop: 16
  },
  spinner: {
    marginTop: 16
  },
  row: {
    flexDirection: 'row',
    paddingTop: 16
  },
  fill: {
    flex: 1
  },
  marginBottom: {
    marginBottom: 16
  },
});

function convertOrderData({ id, displayId, type, delivery, pickup, pricing, payment, promoCodeId, voucherId }) {
  return {
    displayId,
    orderId: id,
    type,
    addressId: delivery.addressId,
    ...((delivery.addressId !== (pickup || delivery).addressId) ? {
      deliveryAddressId: delivery.addressId
    } : {}),
    items: pricing.details.filter(item => item.productId && item.quantity && item.quantityType)
      .map(item => ({ id: item.productId, type: item.quantityType, count: item.quantity, insurance: item.insurance, ...((item.quantityType === 'flower') ? { type: 'subscription' } : {}) })),
    pickupDate: (pickup || delivery).date,
    deliveryDate: delivery.date,
    pickupFlexible: (pickup || delivery).flexible,
    dropOffFlexible: delivery.flexible,
    pickupNote: (pickup || delivery).note,
    deliveryNote: delivery.note,
    express: delivery.express,
    payment: payment && payment.paymentMethod,
    promoCodeId,
    voucherId
  };
}

class OrderDetailPage extends Component {
  static navigationOptions = ({ navigation, screenProps }) => {
    return {
      title: `${screenProps.chinese ? '订单' : 'Order'} #${navigation.state.params.displayId}`,
      headerRight: (
        <TouchableOpacity onPress={() => navigation.navigate('OrderHistory', navigation.state.params)}>
          <Icon style={{ marginRight: 8 }} name='history' color={primaryColor} />
        </TouchableOpacity>
      ),
    };
  }
  state = { processing: false }
  onUpdateItems = () => {
    const { id, type, pickup, delivery, pricing } = this.props.order;
    let details = pricing.details.filter(item => item.productId);
    let results = [];
    details.map(({ productId, quantityType, quantity, insurance }) => {
      const find = results.find(item => item.id == productId);
      if (find) {
        find.insurance = insurance;
        find[`${quantityType}Count`] = (find[`${quantityType}Count`] || 0) + quantity;
      } else {
        results.push({ needLoad: true, id: productId, insurance, [`${quantityType}Count`]: quantity });
      }
    })

    setNewOrderItems(type === 'premiumlaundry', results)
      .then(() => {
        this.props.navigation.navigate('LaundryPricing', {
          ...convertOrderData(this.props.order),
          checkout: true,
          stepper: ['CheckoutOverview'],
          stepIndex: 0
        });
      })
  }
  onNoteOrder = () => this.props.navigation.navigate('OrderNote', this.props.navigation.state.params)
  onPrintOrder = () => {
    printOrder(this.props.order, this.props.worker)
      .catch(err => toast(err));
  }
  onDirection = () => getDirection(this.props.order)
  onFailed = () => this.props.navigation.navigate('PickupDeliveryFailed', {
    ...this.props.navigation.state.params,
    pickupFailed: isPickupOrder(this.props.order.status.statusId),
    deliveryFailed: !isPickupOrder(this.props.order.status.statusId)
  })
  onCallOrder = () => {
    const { pickup, delivery, status } = this.props.order;
    executor(this.props.getUserContact, isPickupOrder(status.statusId) ? pickup.contact : delivery.contact)
      .then(({ res }) => {
        if (res && res.getUserContact) {
          Communications.phonecall(res.getUserContact, false);
        }
        this.setState({ calling: false });
      });
    this.setState({ calling: true });
  }
  onConfirmWithoutCash = () => this.onConfirm(null, true)
  onConfirm = (e, withoutCash) => {
    const isPickup = isPickupOrder(this.props.order.status.statusId);

    if (isPickup && ['laundry', 'premiumlaundry', 'bulkylaundry', 'loadwash'].indexOf(this.props.order.type) >= 0) {
      this.props.navigation.navigate('BagScan', { ...this.props.navigation.state.params, input: true });
    } else {
      Alert.alert(
        isPickup ? 'Confirm Pickup?' : 'Confirm Delivery?',
        (this.props.order.payment.status !== 'Paid' && this.props.order.payment.paymentMethod === 'cash')
          ? (withoutCash ? `Customer havn't give me any cash for order payment`
            : `I already collected $${this.props.order.pricing.toPayPrice} in cash from customer`) : '',
        [
          { text: 'Cancel' },
          {
            text: 'OK', onPress: () => {
              executor(this.props.confirmDelivery, !withoutCash)
                .then(({ res }) => {
                  this.setState({ submitting: false });
                  toast('Success');
                })
              this.setState({ submitting: true });
            }
          },
        ],
      );
    }
  }
  onUpdateLaundryBag = () => this.props.navigation.navigate('BagScan', {
    ...this.props.navigation.state.params,
    laundryBags: this.props.order.laundryBags,
    update: true
  })
  onLaundry = () => this.onNewOrder('laundry')
  onPremiumLaundry = () => this.onNewOrder('premiumlaundry')
  onQuckOrder = (type) => {
    executor(this.props.quickOrder, type)
      .then(({ res }) => {
        if (res) {
          this.props.navigation.navigate('OrderDetail', { displayId: res.quickOrder.displayId, id: res.quickOrder.id });
          toast(`New order #${res.quickOrder.displayId} created and already assigned to you`);
        }
      });
    toast('Placing order', true);
  }
  onNewOrder = (type) => {
    Alert.alert(
      'Order Type',
      null,
      [
        { text: 'Quick Order', onPress: () => this.onQuckOrder(type) },
        {
          text: 'Step by Step', onPress: () => {
            this.props.navigation.navigate('LaundryPricing', {
              type,
              addressId: this.props.order.delivery.addressId,
              pickupDate: this.props.order.delivery.date,
              userId: this.props.order.userId
            });
          }
        },
        { text: 'Cancel' }
      ],
      { cancelable: true }
    );
  }
  render() {
    if (this.props.loading) return <Loader />;
    if (!this.props.order) return null;

    const order = this.props.order;
    const { chinese } = this.props.screenProps;
    const isPickup = isPickupOrder(order.status.statusId);
    const needCollectCash = !isPickup && order.payment.status !== 'Paid' && order.payment.paymentMethod === 'cash';
    const showActionButton = (isPickup ? [1, 2, 3, 10] : [5, 6, 11]).indexOf(order.status.statusId) >= 0;
    const pickupDeliveryFailed = [10, 11].indexOf(order.status.statusId) >= 0;

    return (
      <View style={styles.fill}>
        <View style={[styles.fill, showActionButton ? null : styles.marginBottom]}>
          <RefreshScrollView chinese={chinese} refetch={this.props.refetch}>
            <View style={styles.row}>
              <View style={styles.fill}>
                <Button icon={{ name: 'feedback', color: 'black' }} title='FEEDBACK'
                  backgroundColor='white' color='black' onPress={this.onNoteOrder} />
              </View>
              <View style={styles.fill}>
                <Button icon={{ name: 'print', color: 'black' }} title='PRINT' backgroundColor='white' color='black'
                  onPress={this.onPrintOrder} />
              </View>
            </View>
            <View style={styles.row}>
              <View style={styles.fill}>
                <Button icon={{ name: 'location-on', color: 'black' }} title='MAP' backgroundColor='white'
                  color='black' onPress={this.onDirection} />
              </View>
              <View style={styles.fill}>
                {this.state.calling ? <ActivityIndicator /> : <Button icon={{ name: 'call', color: 'black' }} title='CALL'
                  backgroundColor='white' color='black' onPress={this.onCallOrder} />}
              </View>
            </View>
            <List>
              <ListItem title={order.status.displayStatus} rightTitle='Order status' hideChevron />
            </List>
            {needCollectCash &&
              <List>
                <ListItem containerStyle={{ backgroundColor: '#FFF59D' }} title={`Cash payment: Remember to collect $${order.pricing.toPayPrice} from customer.`} hideChevron />
              </List>
            }
            {isPickup && <OrderShipping chinese={chinese} onUpdateDate={this.onUpdatePickupDate}
              onUpdateAddress={this.onUpdateAddress}
              onUpdateContact={this.onUpdateAddress} onUpdateNote={this.onUpdatePickupNote}
              shipping={filter(OrderShipping.fragments.shipping, order.pickup)} />}
            {!isPickup && <OrderShipping chinese={chinese} onUpdateDate={this.onUpdateDeliveryDate}
              onUpdateAddress={this.onUpdateAddress}
              onUpdateContact={this.onUpdateAddress} onUpdateNote={this.onUpdateDeliveryNote}
              shipping={filter(OrderShipping.fragments.shipping, order.delivery)} />}
            <OrderPricingTable chinese={chinese} pricing={filter(OrderPricingTable.fragments.pricing, order.pricing)}
              onUpdate={this.onUpdateItems} />
            {(showActionButton || (order.status.statusId === 7)) && !isPickup &&
              <View style={styles.paddingTop}>
                <Button backgroundColor='white' color='black' title='New Laundry Order' onPress={this.onLaundry} />
              </View>
            }
            {(showActionButton || (order.status.statusId === 7)) && !isPickup &&
              <View style={styles.paddingTop}>
                <Button backgroundColor='white' color='black' title='New Premium Laundry Order' onPress={this.onPremiumLaundry} />
              </View>
            }
            {showActionButton && !pickupDeliveryFailed &&
              <View style={styles.paddingTop}>
                <Button backgroundColor='#607D8B'
                  title={isPickup ? 'PICKUP FAILED' : 'DROP OFF FAILED'} onPress={this.onFailed} />
              </View>
            }
          </RefreshScrollView>
        </View>
        {this.state.submitting ? <ActivityIndicator style={{ marginVertical: 32 }} /> :
          (showActionButton ?
            <View style={[styles.spinner, styles.marginBottom]}>
              <Button backgroundColor={primaryColor}
                title={(needCollectCash ? `DELIVERED & CASH COLLECTED` : (isPickup ? 'PICKED UP' : 'CONFIRM DELIVERY'))} onPress={this.onConfirm} />
              {needCollectCash &&
                <View style={styles.paddingTop}>
                  <Button backgroundColor='white' color='black'
                    title={'DELIVERED WITHOUT PAYMENT'} onPress={this.onConfirmWithoutCash} />
                </View>
              }
            </View> : null
          )
        }
        {order.status.statusId === 12 &&
          <Button style={styles.marginBottom} backgroundColor='white' color='black'
            title='UPDATE LAUNDRY BAGS' onPress={this.onUpdateLaundryBag} />
        }
      </View>
    );
  }
}

export default compose(
  graphql(gql`
    query order($id:String!) {
      order(id:$id) {
        id
        displayId
        estDate
        type
        userId
        seriesId
        voucherId
        promoCodeId
        canCancel
        warningNotes
        userRef {
          firstName
        }
        payment {
          status
          paymentMethod
        }
        status {
          statusId
          displayStatus
        }
        pricing {
          toPayPrice
          ...OrderPricingTable
        }
        pickup {
          date
          addressId
          contact
          ...OrderShipping
        }
        delivery {
          date
          addressId
          contact
          district
          express
          postalCode
          ...OrderShipping
        }
        laundryBags
      }
      worker {
        id
        firstName
        lastName
      }
    }
    ${OrderPricingTable.fragments.pricing}
    ${OrderShipping.fragments.shipping}
  `, {
    options: ({ navigation }) => {
      return {
        variables: {
          id: navigation.state.params.id
        }
      };
    },
    props: ({ data: { order, worker, loading, refetch } }) => {
      return {
        order,
        worker,
        refetch,
        loading
      };
    }
  }),
  graphql(gql`
    mutation getUserContact($contact:String!) {
      getUserContact(contact:$contact)
    }
  `, {
    name: 'getUserContact',
    props: ({ ownProps: { navigation: { state: { params: { id } } } }, getUserContact }) => {
      return {
        getUserContact: (contact) => getUserContact({ variables: { contact } })
      };
    }
  }),
  graphql(gql`
    mutation confirmDelivery($orderId:String!,$cashReceived:Boolean) {
      confirmDelivery(orderId:$orderId,cashReceived:$cashReceived) {
        id
        payment {
          status
          paymentMethod
        }
        status {
          statusId
        }
      }
    }
  `, {
    name: 'confirmDelivery',
    props: ({ ownProps: { navigation: { state: { params: { id } } } }, confirmDelivery }) => {
      return {
        confirmDelivery: (cashReceived) => confirmDelivery({
          variables: { orderId: id, cashReceived },
          updateQueries: {
            OrderList: (prev, { mutationResult }) => {
              const completeOrder = mutationResult.data.confirmDelivery;
              const index = prev.orders.findIndex(item => item.id === completeOrder.id);

              if (index >= 0) {
                return update(prev, {
                  orders: {
                    $splice: [[index, 1]]
                  }
                });
              } else {
                return prev;
              }
            },
          }
        })
      };
    }
  }),
  graphql(gql`
    mutation quickOrder($type:String!,$orderId:String!) {
      quickOrder(orderId:$orderId,type:$type) {
        id
        displayId
      }
    }
  `, {
    name: 'quickOrder',
    props: ({ ownProps: { navigation: { state: { params: { id } } } }, quickOrder }) => {
      return {
        quickOrder: (type) => quickOrder({ variables: { type, orderId: id } })
      };
    }
  })
)(OrderDetailPage);



